// 优化后的main.go示例
package main

import (
	"context"
	"fmt"
	"io"
	"log"
	"os"
	"strings"

	"github.com/chzyer/readline"
	"github.com/dean2027/aish/pkg/agent"
	"github.com/dean2027/aish/pkg/app"
	"github.com/dean2027/aish/pkg/cli"
	"github.com/dean2027/aish/pkg/config"
	"github.com/dean2027/aish/pkg/ui"
	"github.com/dean2027/aish/pkg/version"
	"github.com/fatih/color"
	cli_lib "github.com/urfave/cli/v2"
)

func main() {
	app := buildApp()
	if err := app.Run(os.Args); err != nil {
		log.Fatal(err)
	}
}

// buildApp 构建CLI应用程序
func buildApp() *cli_lib.App {
	return &cli_lib.App{
		Name:        "aish",
		Usage:       "AI Shell - 基于ReAct架构的智能终端助手",
		Version:     version.GetVersionString(),
		Description: "AISH是一个智能终端工具，通过自然语言描述任务目标，由AI智能体自动分解并执行系统操作",
		Commands:    cli.BuildCommands(),
		Flags:       cli.BuildFlags(),
		Action:      runAISH,
		Before:      validateBeforeRun,
	}
}

// validateBeforeRun 运行前验证
func validateBeforeRun(c *cli_lib.Context) error {
	// 如果是配置子命令，不需要验证配置
	if c.Args().Len() > 0 && c.Args().First() == "config" {
		return nil
	}
	return nil
}

// runAISH 运行AISH主程序
func runAISH(c *cli_lib.Context) error {
	// 1. 加载和合并配置
	cfg, err := loadAndMergeConfig(c)
	if err != nil {
		return handleConfigError(err)
	}

	// 2. 验证配置
	if err := cfg.Validate(); err != nil {
		return handleValidationError(err)
	}

	// 3. 设置环境变量
	setupEnvironment(cfg)

	// 4. 创建和配置组件
	return runMainLoop(cfg)
}

// loadAndMergeConfig 加载和合并配置
func loadAndMergeConfig(c *cli_lib.Context) (*config.Config, error) {
	// 加载配置文件
	configPath := c.String("config")
	cfg, err := config.LoadConfig(configPath)
	if err != nil {
		return nil, fmt.Errorf("配置加载失败: %v", err)
	}

	// 应用环境变量
	cfg.MergeWithEnvVars()

	// 应用CLI参数（优先级最高）
	cli.MergeConfigFromCLI(cfg, c)

	return cfg, nil
}

// handleConfigError 处理配置错误
func handleConfigError(err error) error {
	fmt.Printf("配置加载失败: %v\n", err)
	return err
}

// handleValidationError 处理验证错误
func handleValidationError(err error) error {
	fmt.Printf("配置验证失败: %v\n", err)
	fmt.Println("请通过以下方式之一设置OpenAI API密钥:")
	fmt.Println("  1. 配置文件:   在 ~/.aish/conf.yml 中设置 api_key")
	fmt.Println("  2. 环境变量:   export OPENAI_API_KEY=YOUR_KEY")
	fmt.Println("  3. 命令行参数: --api-key YOUR_KEY")
	return err
}

// setupEnvironment 设置环境变量
func setupEnvironment(cfg *config.Config) {
	if cfg.SkipConfirm {
		os.Setenv("AISH_SKIP_CONFIRM", "true")
	}
}

// runMainLoop 运行主循环
func runMainLoop(cfg *config.Config) error {
	ctx := context.Background()

	// 创建信号管理器
	signalManager := app.NewSignalManager()

	// 创建智能体和引擎
	engine, err := createEngine(cfg)
	if err != nil {
		return err
	}

	// 显示启动横幅
	ui.ShowStartupBanner(cfg, version.GetVersionString())

	// 创建readline实例
	readlineConfig := app.DefaultReadlineConfig()
	rl, err := app.CreateReadline(readlineConfig)
	if err != nil {
		return fmt.Errorf("初始化输入处理失败: %v", err)
	}
	defer rl.Close()

	// 设置信号处理
	signalManager.SetupWithReadline(rl)

	// 主输入循环
	return runInputLoop(ctx, rl, engine)
}

// createEngine 创建执行引擎
func createEngine(cfg *config.Config) (*agent.Engine, error) {
	// 创建智能体配置
	agentConfig := agent.AgentConfig{
		APIKey:           cfg.APIKey,
		BaseURL:          cfg.BaseURL,
		Model:            cfg.Model,
		SerpApiKey:       cfg.SerpApiKey,
		MaxIterations:    cfg.MaxIterations,
		MaxHistory:       cfg.MaxHistory,
		CommandTimeout:   cfg.CommandTimeout,
		ReasoningTimeout: cfg.ReasoningTimeout,
	}

	// 创建智能体
	reactAgent := agent.NewReActAgentWithConfig(agentConfig)

	// 创建执行引擎
	engine, err := agent.NewEngine(reactAgent)
	if err != nil {
		return nil, fmt.Errorf("创建执行引擎失败: %v", err)
	}

	return engine, nil
}

// runInputLoop 运行输入循环
func runInputLoop(ctx context.Context, rl *readline.Instance, engine *agent.Engine) error {
	for {
		input, err := rl.Readline()
		if err != nil {
			if err == readline.ErrInterrupt {
				if len(input) == 0 {
					break
				} else {
					continue
				}
			} else if err == io.EOF {
				break
			}
			color.New(color.FgRed).Printf("读取输入时出错: %v\n", err)
			break
		}

		// 处理输入
		if shouldContinue := processInput(ctx, input, engine); !shouldContinue {
			break
		}
	}

	return nil
}

// processInput 处理用户输入
func processInput(ctx context.Context, input string, engine *agent.Engine) bool {
	input = strings.TrimSpace(input)

	switch {
	case input == "/exit" || input == "/quit":
		return false
	case input == "/clear" || input == "/cls":
		engine.ClearHistory()
		return true
	case input == "":
		return true
	default:
		// 处理任务输入
		if err := engine.ProcessGoal(ctx, input); err != nil {
			color.New(color.FgRed).Printf("错误: %v\n", err)
		}
		fmt.Println("\n" + strings.Repeat("=", 50))
		return true
	}
}
